package com.su.lightthings.update

import android.util.Log
import com.blankj.utilcode.util.FileUtils
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import retrofit2.Retrofit
import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.concurrent.Executors


class DownloadUtil {

    companion object {
        private const val TAG = "DownloadUtil"
    }

    fun download(url: String, path: String, downloadListener: DownloadListener) {
        val downloadUrl = url.replace("https://www.pgyer.com", "", false)
        val retrofit = Retrofit.Builder()
            .baseUrl("https://www.pgyer.com/") //通过线程池获取一个线程，指定callback在子线程中运行。
            .callbackExecutor(Executors.newSingleThreadExecutor())
            .build()
        val service = retrofit.create(DownloadService::class.java)
        val call: Call<ResponseBody> = service.downloadFile(downloadUrl)
        call.enqueue(object : Callback<ResponseBody?> {
            override fun onResponse(call: Call<ResponseBody?>, response: Response<ResponseBody?>) {
                //将Response写入到从磁盘中，详见下面分析
                //注意，这个方法是运行在子线程中的
//                writeResponseToDisk(path, response, downloadListener)
            }

            override fun onFailure(call: Call<ResponseBody?>, throwable: Throwable) {
                downloadListener.onFail("网络错误～")
            }
        })
    }

    fun download(url: String, baseUrl: String, file: File, downloadListener: DownloadListener) {
        val retrofit = Retrofit.Builder()
            .baseUrl(baseUrl) //通过线程池获取一个线程，指定callback在子线程中运行。
            .callbackExecutor(Executors.newSingleThreadExecutor())
            .build()
        val service = retrofit.create(DownloadService::class.java)
        val call: Call<ResponseBody> = service.downloadFile(url)
        Log.d(TAG, "download path : $baseUrl  >>  $url")
        call.enqueue(object : Callback<ResponseBody?> {
            override fun onResponse(call: Call<ResponseBody?>, response: Response<ResponseBody?>) {
                //下载文件的文件名
                val fileName = response.headers().value(4)
                downloadListener.onFileName(fileName)
                //注意，这个方法是运行在子线程中的
                writeResponseToDisk(file, response, downloadListener)
            }

            override fun onFailure(call: Call<ResponseBody?>, throwable: Throwable) {
                downloadListener.onFail("网络错误:${throwable.message}")
            }
        })
    }

    private fun writeResponseToDisk(
//        path: String,
        file:File,
        response: Response<ResponseBody?>,
        downloadListener: DownloadListener
    ) {
        //从response获取输入流以及总大小
        writeFileFromIS(
            file,
            response.body()!!.byteStream(),
            response.body()!!.contentLength(),
            downloadListener
        )
    }

    private val sBufferSize = 8192

    //将输入流写入文件
    private fun writeFileFromIS(
        file: File,
        inputStream: InputStream,
        totalLength: Long,
        downloadListener: DownloadListener
    ) {
        //开始下载
        downloadListener.onStart()

        //删除文件夹下全部文件
        FileUtils.deleteFilesInDir(file)

        //创建文件
        if (!file.exists()) {
            if (!file.parentFile.exists()) {
                file.parentFile.mkdir()
            } else {
            }
            try {
                file.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
                downloadListener.onFail("createNewFile IOException")
            }
        }
        var os: OutputStream? = null
        var currentLength: Long = 0
        try {
            os = BufferedOutputStream(FileOutputStream(file))
            val data = ByteArray(sBufferSize)
            var len: Int
            while (inputStream.read(data, 0, sBufferSize).also { len = it } != -1) {
                os.write(data, 0, len)
                currentLength += len.toLong()
                //计算当前下载进度
                downloadListener.onProgress((100 * currentLength / totalLength).toInt())
            }
            //下载完成，并返回保存的文件路径
            downloadListener.onFinish(file.absolutePath)
        } catch (e: IOException) {
            e.printStackTrace()
            downloadListener.onFail("IOException")
        } finally {
            try {
                inputStream.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            try {
                os?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
}